﻿using System;
using System.Runtime.InteropServices;
using System.IO;
using CLoggerNamespace;
using System.Text;
using System.Globalization;

namespace HSCardReaderNamespace 
{

  public interface IHSCard
  {
     string SName();
	string identificarTarjeta();
    
    bool escribirenTarjeta(string strDatosToW, int inFileSel);
    bool escribirDatos(string strDatosToW, int inFileSelected);

    string SendReceiveCommands(byte byCLA_, byte byINS_, byte byP1_, byte byP2_, string strDatosToSend);
    bool EnviarComandoATarjeta(byte byCLA, byte byINS, byte byP1, byte byP2, string strDatosComando);

    string ContextoChangePin(string strPinToSend, byte[] byICCodeSubmit, byte byIcCodeNoPin);
    bool ChangePin(string strDataToPin,byte[] byICSubmitCode,byte byCodeNo);
    
    bool ContextoUpdateATR(byte[] byN_ATR, byte byCantDigATR, byte[] byATRIcSubCode, byte byCodeNo);
    bool UpdateATR(byte[] byNewATR, byte num_historical_byte, byte[] byICCode, byte byCodeNo);

    string LeerEnTarjeta(int inFileSelected);
    string LeerDatos(int inFileSelector);

    bool DarFormato(byte[] byFormatoICCode, byte byCodeNo);
    string DarFormatoenTarjeta(byte[] byCodeIcFormato, byte byCodeNoFormato);

	string listarLectoras();
	bool conectar();
	bool comenzarTransaccion();
	string leerATR();
	bool establecerContexto();
	bool terminarTransaccion();
	bool desconectar();
	bool soltarContexto();
      
  }
	

  [ClassInterface(ClassInterfaceType.AutoDual)]
  public class HSCardClass : IHSCard
  {
		#region Properties
                string _strLectora;
                // variable declaration
                int Protocol, hContext, hCard, ReaderCount;
                int retCode;
                int ActiveProtocol, retcode;  
                //byte[] sReaderList = new byte [255];
                string sReaderList;
                string sReaderGroup;
                
                public ModWinsCard.SCARD_IO_REQUEST ioRequest = new ModWinsCard.SCARD_IO_REQUEST();
                int SendLen, RecvLen;
                byte[] SendBuff = new byte[262];
                byte[] RecvBuff = new byte[262];

                int indx, SendBuffLen, RecvBuffLen;         //FD v1.01

                byte[] tmpArray = new byte[56];     //FD v1.01
                byte HiAddr, LoAddr, dataLen;       //FD v1.01
                byte[] array = new byte[256];       //FD v1.01
                int Aprotocol, i;                   //FD v1.01

                string tmpStr;                      //FD            //ATR
                string sTemp;                       //FD v1.01      //COMANDO o datos DE RESPUESTA 

      //////////////////////////////////////////////////////////                
                public int inLongitudFile1 = 10;
                public int inLongitudFile2 = 16;
                public int inLongitudFile3 = 32;
                public int inLongitudFile4 = 64;

        #endregion

  // byte[] SendBuff = new byte[262];
   ModWinsCard.APDURec apdu = new ModWinsCard.APDURec();	


    public string SName()
    {
		if(establecerContexto())
		{
			if(soltarContexto())
			{
			return "Contexto OK";
			}
			else
			{
			return "Soltar NOK";
			}
		}
		else
		{
			return "Contexto NOK";
		}
      
    }
   
	
	 	#region Metodos Principales
		public string identificarTarjeta()
		{                    
		    string strATR="";
			if(!establecerContexto())
			{
                CLogger.Append("ERROR: ERROR en establecerContexto()", CLogger.COMM);
				return "ERROR en establecerContexto()";
			}
			if(listarLectoras()=="ERROR")
			{
				if(!soltarContexto())
				{
                    CLogger.Append("ERROR: ERROR GRAVE en listarLectoras()", CLogger.COMM);
					return "ERROR GRAVE en listarLectoras()";
				}
                CLogger.Append("ERROR: ERROR en listarLectoras()", CLogger.COMM);
				return "ERROR en listarLectoras()";
			}
			if(!conectar())
			{			
				if(!soltarContexto())
					{
                        CLogger.Append("ERROR: ERROR GRAVE en conectar()", CLogger.COMM);
						return "ERROR GRAVE en conectar()";
					}
                CLogger.Append("ERROR: ERROR en conectar()", CLogger.COMM);
				return "ERROR en conectar()";
			}
			if(!comenzarTransaccion())
			{			
				if(!desconectar())
					{
                        CLogger.Append("ERROR: ERROR GRAVE 1 en comenzarTransaccion()", CLogger.COMM);
						return "ERROR GRAVE 1 en comenzarTransaccion()";
					}
				if(!soltarContexto())
					{
                        CLogger.Append("ERROR: ERROR GRAVE 2 en comenzarTransaccion()", CLogger.COMM);
						return "ERROR GRAVE 2 en comenzarTransaccion()";
					}
                CLogger.Append("ERROR: ERROR en comenzarTransaccion()", CLogger.COMM);
				return "ERROR en comenzarTransaccion()";
			}
			strATR = leerATR();
			if(strATR=="ERROR")
			{
				if(!terminarTransaccion())
					{
                        CLogger.Append("ERROR: ERROR GRAVE 1 en leerATR()", CLogger.COMM);
						return "ERROR GRAVE 1 en leerATR()";
					}
				if(!desconectar())
					{
                        CLogger.Append("ERROR: ERROR GRAVE 2 en leerATR()", CLogger.COMM);
						return "ERROR GRAVE 2 en leerATR()";
					}
				if(!soltarContexto())
					{
                        CLogger.Append("ERROR: ERROR GRAVE 3 en leerATR()", CLogger.COMM);
                        return "ERROR GRAVE 3 en leerATR()";
					}
                CLogger.Append("ERROR: ERROR en leerATR()", CLogger.COMM);
				return "ERROR en leerATR()";
			}
			if(!terminarTransaccion())
			{
				if(!desconectar())
						{
                            CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
							return "ERROR GRAVE 1 en terminarTransaccion()";
						}
				if(!soltarContexto())
					{
                        CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
						return "ERROR GRAVE 2 en terminarTransaccion()";
					}
                CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
				return "ERROR en terminarTransaccion()";
			}
			if(!desconectar())
			{
				if(!soltarContexto())
					{
                        CLogger.Append("ERROR: ERROR GRAVE en desconectar()", CLogger.COMM);
						return "ERROR GRAVE en desconectar()";
					}
                CLogger.Append("ERROR: ERROR en desconectar()", CLogger.COMM);
				return "ERROR en desconectar()";
			}
			if(!soltarContexto())
			{
                CLogger.Append("ERROR: ERROR en soltarContexto() ", CLogger.COMM);
                return "ERROR en soltarContexto()";             
            }

            CLogger.Append("Identificar Tarjeta: IDENTIFIQUE ATR ", CLogger.COMM);
			return strATR;
		}

      /// <summary>
      /// Escribir en la tarjeta
      /// </summary>
      /// <returns></returns>
       public bool escribirenTarjeta(string strDatosToW,int inFileSel)
        {
           // CLogger.Append("Escribir en Tarjeta: ENTRE DAT:" + strDatosToW, CLogger.COMM);
            //EscribirLog("Llegue a la funcion");
           
            if (!establecerContexto())
            {
                CLogger.Append("ERROR: ERROR en establecerContexto() ", CLogger.COMM);
                return false;
            }
            if (listarLectoras() == "ERROR")
            {
                if (!soltarContexto())
                {
                    CLogger.Append("ERROR: ERROR GRAVE en listarLectoras() ", CLogger.COMM);
                    return false;
                }
                CLogger.Append("ERROR: ERROR en listarLectoras()", CLogger.COMM);
                return false;
            }
            if (!conectar())
            {
                if (!soltarContexto())
                {
                    CLogger.Append("ERROR: ERROR GRAVE en conectar()", CLogger.COMM);
                    return false;
                }
                CLogger.Append("ERROR: ERROR en conectar()", CLogger.COMM);
                return false;
            }
            if (!comenzarTransaccion())
            {
                if (!desconectar())
                {
                    CLogger.Append("ERROR: ERROR GRAVE 1 en comenzarTransaccion()", CLogger.COMM);
                    return false;
                }
                if (!soltarContexto())
                {
                    CLogger.Append("escribirenTarjeta(...): ERROR GRAVE 2 en comenzarTransaccion()", CLogger.COMM);
                    return false;
                }
                CLogger.Append("ERROR: ERROR en comenzarTransaccion()", CLogger.COMM);
                return false;
            }

            if (!escribirDatos(strDatosToW, inFileSel))  //FD v1.01
            {
                if (!terminarTransaccion())
                {
                    CLogger.Append("ERROR: ERROR GRAVE 1 en escribirDatos(DatosToW)", CLogger.COMM);
                    return false;
                }
                if (!desconectar())
                {
                    CLogger.Append("ERROR: ERROR GRAVE 2 en escribirDatos(DatosToW)", CLogger.COMM);
                    return false;
                }
                if (!soltarContexto())
                {
                    CLogger.Append("ERROR: ERROR GRAVE 3 en escribirDatos(DatosToW)", CLogger.COMM);
                    return false;
                }

                CLogger.Append("ERROR: ERROR en escribirDatos(DatosToW)", CLogger.COMM);
                return false;
            
            }

            if (!terminarTransaccion())
            {
                if (!desconectar())
                {
                    CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                    return false;
                }
                if (!soltarContexto())
                {
                    CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                    return false;
                }
                CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
                return false;
            }
            if (!desconectar())
            {
                if (!soltarContexto())
                {
                    CLogger.Append("ERROR: ERROR GRAVE en desconectar()", CLogger.COMM);
                    return false;
                }
                CLogger.Append("ERROR: ERROR en desconectar()", CLogger.COMM);
                return false;
            }
            if (!soltarContexto())
            {
                CLogger.Append("ERROR: ERROR en soltarContexto()", CLogger.COMM);
                return false;
            }
            CLogger.Append("Escritura correcta", CLogger.COMM);
           
           return true;
        }

      //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       /// <summary>
       /// SEND RECEIVE COMMANDS              ///////////////////////////////////////////////////////////////////////////////
       /// </summary>
       /// <returns></returns>
       /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public string SendReceiveCommands(byte byCLA_,byte byINS_,byte byP1_,byte byP2_,string strDatosToSend)
       {
           // CLogger.Append("Escribir en Tarjeta: ENTRE DAT:" + strDatosToW, CLogger.COMM);
           //EscribirLog("Llegue a la funcion");

           if (!establecerContexto())
           {
               CLogger.Append("ERROR: ERROR en establecerContexto() ", CLogger.COMM);
               return null;
           }
           if (listarLectoras() == "ERROR")
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en listarLectoras() ", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en listarLectoras()", CLogger.COMM);
               return null;
           }
           if (!conectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en conectar()", CLogger.COMM);
                   return "ERROR GRAVE en conectar()";
               }
               CLogger.Append("ERROR: ERROR en conectar()", CLogger.COMM);
               return null;
           }
           if (!comenzarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en comenzarTransaccion()", CLogger.COMM);
                   return "ERROR GRAVE 1 en comenzarTransaccion()";
               }
               if (!soltarContexto())
               {
                   CLogger.Append("escribirenTarjeta(...): ERROR GRAVE 2 en comenzarTransaccion()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en comenzarTransaccion()", CLogger.COMM);
               return null;
           }
           ///////////////////////////////////ENVIO  TR //////////////////////////
           if(!EnviarComandoATarjeta(byCLA_, byINS_, byP1_, byP2_,strDatosToSend))
           {
               if (!terminarTransaccion())
               {
                   CLogger.Append("ERROR: ERROR GRAVE  en EnviarComandoATarjeta(..)", CLogger.COMM);
                   return "ERROR GRAVE  en EnviarComandoATarjeta(..)";
			
               }
               if (!desconectar())
                {
                    CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                    return null;
                }
                if (!soltarContexto())
                {
                    CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                    return null;
                }
                CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
                return null;
           }
           ///////////////////////////////////TERMINAR TR //////////////////////////
           if (!terminarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
               return null;
           }
           if (!desconectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en desconectar()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en desconectar()", CLogger.COMM);
               return null;
           }
           if (!soltarContexto())
           {
               CLogger.Append("ERROR: ERROR en soltarContexto()", CLogger.COMM);
               return null;
           }
           
           CLogger.Append("SEND RECEIVE COMMANDS  correcto", CLogger.COMM);

           //return tmpStr; //ATR
           return sTemp;        //COMANDO o datos DE RESPUESTA 

       }

       



       /// <summary>    /////////////////////////////////////////////////////////////////////////////////////////////////////
       /// Leer en la tarjeta                   ///////////////////////////////////////////////////////////////////////////////
       /// </summary>
       /// <returns></returns>
       public string LeerEnTarjeta(int inFileSelected)
       {
           string strDatosLeidosTarjeta;
           // CLogger.Append(" ENTRE LEER DAT:" , CLogger.COMM);
           //EscribirLog("Llegue a la funcion");

           if (!establecerContexto())
           {
               CLogger.Append("ERROR: ERROR en establecerContexto() ", CLogger.COMM);
               return "ERROR en establecerContexto()";
           }
           if (listarLectoras() == "ERROR")
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en listarLectoras() ", CLogger.COMM);
                   return "ERROR GRAVE en listarLectoras()";
               }
               CLogger.Append("ERROR: ERROR en listarLectoras()", CLogger.COMM);
               return "ERROR en listarLectoras()";
           }
           if (!conectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en conectar()", CLogger.COMM);
                   return "ERROR GRAVE en conectar()";
               }
               CLogger.Append("ERROR: ERROR en conectar()", CLogger.COMM);
               return "ERROR en conectar()";
           }
           if (!comenzarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en comenzarTransaccion()", CLogger.COMM);
                   return "ERROR GRAVE 1 en comenzarTransaccion()";
               }
               if (!soltarContexto())
               {
                   CLogger.Append("escribirenTarjeta(...): ERROR GRAVE 2 en comenzarTransaccion()", CLogger.COMM);
                   return "ERROR GRAVE 2 en comenzarTransaccion()";
               }
               CLogger.Append("ERROR: ERROR en comenzarTransaccion()", CLogger.COMM);
               return "ERROR en comenzarTransaccion()";
           }
           strDatosLeidosTarjeta = LeerDatos(inFileSelected);
           if (strDatosLeidosTarjeta == "ERROR")  //FD v1.01
           {
               if (!terminarTransaccion())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en strDatosLeidosTarjeta", CLogger.COMM);
                   return "ERROR GRAVE 1 en strDatosLeidosTarjeta";
               }
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en strDatosLeidosTarjeta", CLogger.COMM);
                   return "ERROR GRAVE 2 en strDatosLeidosTarjeta";
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 3 en strDatosLeidosTarjeta", CLogger.COMM);
                   return "ERROR GRAVE 3 en strDatosLeidosTarjeta";
               }

               CLogger.Append("ERROR: ERROR en escribirDatos(DatosToW)", CLogger.COMM);
               return "ERROR en escribirDatos(DatosToW)";

           }

           if (!terminarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                   return "ERROR GRAVE 1 en terminarTransaccion()";
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                   return "ERROR GRAVE 2 en terminarTransaccion()";
               }
               CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
               return "ERROR en terminarTransaccion()";
           }
           if (!desconectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en desconectar()", CLogger.COMM);
                   return "ERROR GRAVE en desconectar()";
               }
               CLogger.Append("ERROR: ERROR en desconectar()", CLogger.COMM);
               return "ERROR en desconectar()";
           }
           if (!soltarContexto())
           {
               CLogger.Append("ERROR: ERROR en soltarContexto()", CLogger.COMM);
               return "ERROR en soltarContexto()";
           }
           CLogger.Append("Lectura correcta", CLogger.COMM);
           return strDatosLeidosTarjeta;
       }

       /// <summary>
       /// Listar Lectoras Cards
       /// </summary>
       /// <returns></returns>
       public string ListarLectorasCards()
       {
           string strLectoraListada;

           if (!establecerContexto())
           {
               CLogger.Append("ERROR: ERROR en establecerContexto() ", CLogger.COMM);
               return "ERROR en establecerContexto()";
           }
           
           strLectoraListada = listarLectoras();
           if (strLectoraListada == "ERROR")
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en listarLectoras() ", CLogger.COMM);
                   return "ERROR GRAVE en listarLectoras()";
               }
               CLogger.Append("ERROR: ERROR en listarLectoras()", CLogger.COMM);
               return "ERROR en listarLectoras()";
           }           
           if (!soltarContexto())
           {
               CLogger.Append("ERROR: ERROR en soltarContexto()", CLogger.COMM);
               return "ERROR en soltarContexto()";
           }
           CLogger.Append("Lectora Listada Correctamente", CLogger.COMM);
           return strLectoraListada;
       }


       /// <summary>
       /// Dar formato a la tarjeta
       /// </summary>
       /// <returns></returns>
       public string DarFormatoenTarjeta(byte[] byCodeIcFormato,byte byCodeNoFormato)
       {
           // CLogger.Append(" ENTRE Dar Formato:" , CLogger.COMM);
           //EscribirLog("Llegue a la funcion");

           if (!establecerContexto())
           {
               CLogger.Append("ERROR: ERROR en establecerContexto() ", CLogger.COMM);
               return "ERROR en establecerContexto()";
           }
           if (listarLectoras() == "ERROR")
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en listarLectoras() ", CLogger.COMM);
                   return "ERROR GRAVE en listarLectoras()";
               }
               CLogger.Append("ERROR: ERROR en listarLectoras()", CLogger.COMM);
               return "ERROR en listarLectoras()";
           }
           if (!conectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en conectar()", CLogger.COMM);
                   return "ERROR GRAVE en conectar()";
               }
               CLogger.Append("ERROR: ERROR en conectar()", CLogger.COMM);
               return "ERROR en conectar()";
           }
           if (!comenzarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en comenzarTransaccion()", CLogger.COMM);
                   return "ERROR GRAVE 1 en comenzarTransaccion()";
               }
               if (!soltarContexto())
               {
                   CLogger.Append("escribirenTarjeta(...): ERROR GRAVE 2 en comenzarTransaccion()", CLogger.COMM);
                   return "ERROR GRAVE 2 en comenzarTransaccion()";
               }
               CLogger.Append("ERROR: ERROR en comenzarTransaccion()", CLogger.COMM);
               return "ERROR en comenzarTransaccion()";
           }

           if (!DarFormato(byCodeIcFormato, byCodeNoFormato))  //FD v1.01
           {
               if (!terminarTransaccion())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en strDatosLeidosTarjeta", CLogger.COMM);
                   return "ERROR GRAVE 1 en strDatosLeidosTarjeta";
               }
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en strDatosLeidosTarjeta", CLogger.COMM);
                   return "ERROR GRAVE 2 en strDatosLeidosTarjeta";
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 3 en strDatosLeidosTarjeta", CLogger.COMM);
                   return "ERROR GRAVE 3 en strDatosLeidosTarjeta";
               }

               CLogger.Append("ERROR: ERROR en escribirDatos(DatosToW)", CLogger.COMM);
               return "ERROR en escribirDatos(DatosToW)";
            }
           if (!terminarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                   return "ERROR GRAVE 1 en terminarTransaccion()";
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                   return "ERROR GRAVE 2 en terminarTransaccion()";
               }
               CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
               return "ERROR en terminarTransaccion()";
           }
           if (!desconectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en desconectar()", CLogger.COMM);
                   return "ERROR GRAVE en desconectar()";
               }
               CLogger.Append("ERROR: ERROR en desconectar()", CLogger.COMM);
               return "ERROR en desconectar()";
           }
           if (!soltarContexto())
           {
               CLogger.Append("ERROR: ERROR en soltarContexto()", CLogger.COMM);
               return "ERROR en soltarContexto()";
           }
           CLogger.Append("Lectura correcta", CLogger.COMM);
           return "OK";
       }

       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       /// <summary>
       /// CAMBIAR O CREAR PIN EN TARJETA             ///////////////////////////////////////////////////////////////////////////////
       /// </summary>
       /// <returns></returns>
       /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public string ContextoChangePin(string strPinToSend,byte[] byICCodeSubmit,byte byIcCodeNoPin)
       {
           // CLogger.Append("Escribir en Tarjeta: ENTRE DAT:" + strDatosToW, CLogger.COMM);
           //EscribirLog("Llegue a la funcion");

           if (!establecerContexto())
           {
               CLogger.Append("ERROR: ERROR en establecerContexto() ", CLogger.COMM);
               return null;
           }
           if (listarLectoras() == "ERROR")
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en listarLectoras() ", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en listarLectoras()", CLogger.COMM);
               return null;
           }
           if (!conectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en conectar()", CLogger.COMM);
                   return "ERROR GRAVE en conectar()";
               }
               CLogger.Append("ERROR: ERROR en conectar()", CLogger.COMM);
               return null;
           }
           if (!comenzarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en comenzarTransaccion()", CLogger.COMM);
                   return "ERROR GRAVE 1 en comenzarTransaccion()";
               }
               if (!soltarContexto())
               {
                   CLogger.Append("escribirenTarjeta(...): ERROR GRAVE 2 en comenzarTransaccion()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en comenzarTransaccion()", CLogger.COMM);
               return null;
           }
           ///////////////////////////////////ENVIO  TR //////////////////////////
           if (!ChangePin(strPinToSend, byICCodeSubmit, byIcCodeNoPin))
           {
               if (!terminarTransaccion())
               {
                   CLogger.Append("ERROR: ERROR GRAVE  en EnviarComandoATarjeta(..)", CLogger.COMM);
                   return "ERROR GRAVE  en EnviarComandoATarjeta(..)";

               }
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
               return null;
           }
           ///////////////////////////////////TERMINAR TR //////////////////////////
           if (!terminarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
               return null;
           }
           if (!desconectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en desconectar()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en desconectar()", CLogger.COMM);
               return null;
           }
           if (!soltarContexto())
           {
               CLogger.Append("ERROR: ERROR en soltarContexto()", CLogger.COMM);
               return null;
           }

           CLogger.Append("SEND RECEIVE COMMANDS  correcto", CLogger.COMM);

           //return tmpStr; //ATR
           return sTemp;        //COMANDO o datos DE RESPUESTA 

       }

      //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       /// <summary>
       /// SELECT FILE (FILE ID)            ///////////////////////////////////////////////////////////////////////////////
       /// </summary>
       /// <returns></returns>
       /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      public string ContextoSelectFile(byte[] strDataSelectFile)
      {
          if (!establecerContexto())
          {
              CLogger.Append("ERROR: ERROR en establecerContexto() ", CLogger.COMM);
              return null;
          }
          if (listarLectoras() == "ERROR")
          {
              if (!soltarContexto())
              {
                  CLogger.Append("ERROR: ERROR GRAVE en listarLectoras() ", CLogger.COMM);
                  return null;
              }
              CLogger.Append("ERROR: ERROR en listarLectoras()", CLogger.COMM);
              return null;
          }
          if (!conectar())
          {
              if (!soltarContexto())
              {
                  CLogger.Append("ERROR: ERROR GRAVE en conectar()", CLogger.COMM);
                  return "ERROR GRAVE en conectar()";
              }
              CLogger.Append("ERROR: ERROR en conectar()", CLogger.COMM);
              return null;
          }
          if (!comenzarTransaccion())
          {
              if (!desconectar())
              {
                  CLogger.Append("ERROR: ERROR GRAVE 1 en comenzarTransaccion()", CLogger.COMM);
                  return "ERROR GRAVE 1 en comenzarTransaccion()";
              }
              if (!soltarContexto())
              {
                  CLogger.Append("escribirenTarjeta(...): ERROR GRAVE 2 en comenzarTransaccion()", CLogger.COMM);
                  return null;
              }
              CLogger.Append("ERROR: ERROR en comenzarTransaccion()", CLogger.COMM);
              return null;
          }
          ///////////////////////////////////ENVIO  TR //////////////////////////
          if (!SelectFileByFileID(strDataSelectFile))
          {
              if (!terminarTransaccion())
              {
                  CLogger.Append("ERROR: ERROR GRAVE  en SelectFileByFileID(..)", CLogger.COMM);
                  return "ERROR GRAVE  en terminarTransaccion(..)";

              }
              if (!desconectar())
              {
                  CLogger.Append("ERROR: ERROR GRAVE 1 en SelectFileByFileID()", CLogger.COMM);
                  return null;
              }
              if (!soltarContexto())
              {
                  CLogger.Append("ERROR: ERROR GRAVE 2 en SelectFileByFileID()", CLogger.COMM);
                  return null;
              }
              CLogger.Append("ERROR: ERROR en SelectFileByFileID()", CLogger.COMM);
              return null;
          }
          ///////////////////////////////////TERMINAR TR //////////////////////////
          if (!terminarTransaccion())
          {
              if (!desconectar())
              {
                  CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                  return null;
              }
              if (!soltarContexto())
              {
                  CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                  return null;
              }
              CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
              return null;
          }
          if (!desconectar())
          {
              if (!soltarContexto())
              {
                  CLogger.Append("ERROR: ERROR GRAVE en desconectar()", CLogger.COMM);
                  return null;
              }
              CLogger.Append("ERROR: ERROR en desconectar()", CLogger.COMM);
              return null;
          }
          if (!soltarContexto())
          {
              CLogger.Append("ERROR: ERROR en soltarContexto()", CLogger.COMM);
              return null;
          }

          CLogger.Append("SEND RECEIVE COMMANDS  correcto", CLogger.COMM);

          //return tmpStr; //ATR
          return sTemp;        //COMANDO o datos DE RESPUESTA 

      }

       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       /// <summary>
       /// SUBMIT CODE TO CARD     - CIERRA CONEXION       ///////////////////////////////////////////////////////////////////////////////
       /// </summary>
       /// <returns></returns>
       /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public string ContextoSubmitCodeToCard(string strDataToSend, byte byP1Data)
       {
           // CLogger.Append("Escribir en Tarjeta: ENTRE DAT:" + strDatosToW, CLogger.COMM);
           //EscribirLog("Llegue a la funcion");

           if (!establecerContexto())
           {
               CLogger.Append("ERROR: ERROR en establecerContexto() ", CLogger.COMM);
               return null;
           }
           if (listarLectoras() == "ERROR")
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en listarLectoras() ", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en listarLectoras()", CLogger.COMM);
               return null;
           }
           if (!conectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en conectar()", CLogger.COMM);
                   return "ERROR GRAVE en conectar()";
               }
               CLogger.Append("ERROR: ERROR en conectar()", CLogger.COMM);
               return null;
           }
           if (!comenzarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en comenzarTransaccion()", CLogger.COMM);
                   return "ERROR GRAVE 1 en comenzarTransaccion()";
               }
               if (!soltarContexto())
               {
                   CLogger.Append("escribirenTarjeta(...): ERROR GRAVE 2 en comenzarTransaccion()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en comenzarTransaccion()", CLogger.COMM);
               return null;
           }
           ///////////////////////////////////ENVIO  TR //////////////////////////
           if (!SubmitCodeToCard(strDataToSend,byP1Data))
           {
               if (!terminarTransaccion())
               {
                   CLogger.Append("ERROR: ERROR GRAVE  en EnviarComandoATarjeta(..)", CLogger.COMM);
                   return "ERROR GRAVE  en EnviarComandoATarjeta(..)";

               }
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
               return null;
           }
           ///////////////////////////////////TERMINAR TR //////////////////////////
           if (!terminarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
               return null;
           }
           if (!desconectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en desconectar()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en desconectar()", CLogger.COMM);
               return null;
           }
           if (!soltarContexto())
           {
               CLogger.Append("ERROR: ERROR en soltarContexto()", CLogger.COMM);
               return null;
           }

           CLogger.Append("SEND RECEIVE COMMANDS  correcto", CLogger.COMM);

           //return tmpStr; //ATR
           return sTemp;        //COMANDO o datos DE RESPUESTA 

       }



       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       /// <summary>
       /// SUBMIT CODE TO CARD            ///////////////////////////////////////////////////////////////////////////////
       /// </summary>
       /// <returns></returns>
       /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public string ContextoGetCardInfo(byte byP1Data, byte byP3Data)
       {
           // CLogger.Append("Escribir en Tarjeta: ENTRE DAT:" + strDatosToW, CLogger.COMM);
           //EscribirLog("Llegue a la funcion");

           if (!establecerContexto())
           {
               CLogger.Append("ERROR: ERROR en establecerContexto() ", CLogger.COMM);
               return null;
           }
           if (listarLectoras() == "ERROR")
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en listarLectoras() ", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en listarLectoras()", CLogger.COMM);
               return null;
           }
           if (!conectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en conectar()", CLogger.COMM);
                   return "ERROR GRAVE en conectar()";
               }
               CLogger.Append("ERROR: ERROR en conectar()", CLogger.COMM);
               return null;
           }
           if (!comenzarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en comenzarTransaccion()", CLogger.COMM);
                   return "ERROR GRAVE 1 en comenzarTransaccion()";
               }
               if (!soltarContexto())
               {
                   CLogger.Append("escribirenTarjeta(...): ERROR GRAVE 2 en comenzarTransaccion()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en comenzarTransaccion()", CLogger.COMM);
               return null;
           }
           ///////////////////////////////////ENVIO  TR //////////////////////////
           if (!GetCardInfo(byP1Data, byP3Data))
           {
               if (!terminarTransaccion())
               {
                   CLogger.Append("ERROR: ERROR GRAVE  en EnviarComandoATarjeta(..)", CLogger.COMM);
                   return "ERROR GRAVE  en EnviarComandoATarjeta(..)";

               }
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
               return null;
           }
           ///////////////////////////////////TERMINAR TR //////////////////////////
           if (!terminarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
               return null;
           }
           if (!desconectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en desconectar()", CLogger.COMM);
                   return null;
               }
               CLogger.Append("ERROR: ERROR en desconectar()", CLogger.COMM);
               return null;
           }
           if (!soltarContexto())
           {
               CLogger.Append("ERROR: ERROR en soltarContexto()", CLogger.COMM);
               return null;
           }

           CLogger.Append("SEND RECEIVE COMMANDS  correcto", CLogger.COMM);

           //return tmpStr; //ATR
           return sTemp;        //COMANDO o datos DE RESPUESTA 

       }


       //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       /// <summary>
       /// SUBMIT CODE TO CARD            ///////////////////////////////////////////////////////////////////////////////
       /// </summary>
       /// <returns></returns>
       /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
       public bool ContextoUpdateATR(byte[] byN_ATR, byte byCantDigATR, byte[] byATRIcSubCode, byte byCodeNo)
       {
           // CLogger.Append("Escribir en Tarjeta: ENTRE DAT:" + strDatosToW, CLogger.COMM);
           //EscribirLog("Llegue a la funcion");

           if (!establecerContexto())
           {
               CLogger.Append("ERROR: ERROR en establecerContexto() ", CLogger.COMM);
               return false;
           }
           if (listarLectoras() == "ERROR")
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en listarLectoras() ", CLogger.COMM);
                   return false;
               }
               CLogger.Append("ERROR: ERROR en listarLectoras()", CLogger.COMM);
               return false;
           }
           if (!conectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en conectar()", CLogger.COMM);
                   return false;
               }
               CLogger.Append("ERROR: ERROR en conectar()", CLogger.COMM);
               return false;
           }
           if (!comenzarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en comenzarTransaccion()", CLogger.COMM);
                   return false;
               }
               if (!soltarContexto())
               {
                   CLogger.Append("escribirenTarjeta(...): ERROR GRAVE 2 en comenzarTransaccion()", CLogger.COMM);
                   return false;
               }
               CLogger.Append("ERROR: ERROR en comenzarTransaccion()", CLogger.COMM);
               return false;
           }
           ///////////////////////////////////ENVIO  TR //////////////////////////
           if (!UpdateATR(byN_ATR, byCantDigATR, byATRIcSubCode,byCodeNo))
           {
               if (!terminarTransaccion())
               {
                   CLogger.Append("ERROR: ERROR GRAVE  en terminarTransaccion()", CLogger.COMM);
                   return false;

               }
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en Desconectar()", CLogger.COMM);
                   return false;
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en SoltarContexto()", CLogger.COMM);
                   return false;
               }
               CLogger.Append("ERROR: ERROR en UpdateATR(strN_ATR,inCantDigATR)", CLogger.COMM);
               return false;
           }
           ///////////////////////////////////TERMINAR TR //////////////////////////
           if (!terminarTransaccion())
           {
               if (!desconectar())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 1 en terminarTransaccion()", CLogger.COMM);
                   return false;
               }
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE 2 en terminarTransaccion()", CLogger.COMM);
                   return false;
               }
               CLogger.Append("ERROR: ERROR en terminarTransaccion()", CLogger.COMM);
               return false;
           }
           if (!desconectar())
           {
               if (!soltarContexto())
               {
                   CLogger.Append("ERROR: ERROR GRAVE en desconectar()", CLogger.COMM);
                   return false;
               }
               CLogger.Append("ERROR: ERROR en desconectar()", CLogger.COMM);
               return false;
           }
           if (!soltarContexto())
           {
               CLogger.Append("ERROR: ERROR en soltarContexto()", CLogger.COMM);
               return false;
           }

           CLogger.Append("SEND RECEIVE COMMANDS  correcto", CLogger.COMM);

           //return tmpStr; //ATR
           //return sTemp;        //COMANDO o datos DE RESPUESTA 
           return true;

       }
        #endregion


      #region Metodos TARJETA

       ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     // #########################################################################################################################
      ///   METODOS DE LA TARJETA !!!!!!!!!!!
      //#########################################################################################################################
      ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

      
      #region Escribir datos
        public bool escribirDatos(string strDatosToW,int inFileSelected)
        {            
            //int a = 3;
            int inInd;

            CLogger.Append("ERROR: strDatosToW: " + strDatosToW, CLogger.COMM);

            
            // Validate input template
            if (strDatosToW == null)
            {
                CLogger.Append("ERROR: strDatosToW NULL", CLogger.COMM);
                return false;
            }

            //Check User File selected by user
            if (inFileSelected == 1)  //10
            {
                HiAddr = 0xAA;
                LoAddr = 0x11;
                dataLen = 0x0A;
                //ChkStr = "91 00";
            }

            if (inFileSelected == 2) //16
            {
                HiAddr = 0xBB;
                LoAddr = 0x22;
                dataLen = 0x10;
                //ChkStr = "91 01";
            }

            if (inFileSelected == 3) //32
            {
                HiAddr = 0xCC;
                LoAddr = 0x33;
                dataLen = 0x20;  //32 bytes
                //ChkStr = "91 02"; 
            }
            
            if (inFileSelected == 4) //32
            {
                HiAddr = 0xDD;
                LoAddr = 0x44;
                dataLen = 0x40;     //  64 bytes
                //ChkStr = "91 02";
            }
          
             SelectFile(HiAddr, LoAddr);    //

         //   if (retcode != ModWinsCard.SCARD_S_SUCCESS)
         //   {
         //       return;
         //   }
            

            tmpStr = "";
            tmpStr = strDatosToW;

            for (inInd = 0; inInd < tmpStr.Length; inInd++)
                tmpArray[inInd] = (byte)Asc(tmpStr.Substring(inInd, 1));

            writeRecord(0x01, 0x00, dataLen, dataLen, ref tmpArray);

            if (retcode != ModWinsCard.SCARD_S_SUCCESS)
            {
                //return;
                return false;
            }

           // lstOutput.Items.Add("Data read from Text Box is written to card.");
            CLogger.Append("Datos leidos estan siendo grabados en la tarjeta.", CLogger.COMM);
            //EscribirLog("Data read from Text Box is written to card.");
           // lstOutput.SelectedIndex = lstOutput.Items.Count - 1;

            int ReaderLen, dwState, ATRLen, indx;
            byte[] ATRVal = new byte[31];
            ATRLen = 32;

            ReaderLen = 0;
            dwState = 0;

            retCode = ModWinsCard.SCardStatus(hCard, _strLectora, ref ReaderLen, ref dwState,
                ref Protocol, ref ATRVal[0], ref ATRLen);
            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
            {//   return "ERROR";
                CLogger.Append("retCode != ModWinsCard.SCARD_S_SUCCESS", CLogger.COMM);
                return false;
            }
            //'Format ATRVal returned and display string as ATR value
            tmpStr = "";
            for (indx = 0; indx < ATRLen; indx++)
            {
                tmpStr = tmpStr + string.Format("{0:x2}", ATRVal[indx]).ToUpper();
            }
           // return tmpStr;

            return true;
        }
        #endregion


        #region Metodos y comandos tarjeta
        ///////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// // ENVIAR COMANDO A TARJETA
        /// </summary>
        /// <param name="strLine"></param>
        /// //////////////////////////////////////////////////////////////////////////////////////////////////
        public bool EnviarComandoATarjeta(byte byCLA, byte byINS, byte byP1, byte byP2, string strDatosComando)
        {

            //Send IC Code
            apdu.Data = array;

            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            Byte[] bytesToSend = encoding.GetBytes(strDatosComando);
            
            apdu.bCLA = byCLA;          // CLA
            apdu.bINS = byINS;          // INS
            apdu.bP1 = byP1;           // P1
            apdu.bP2 = byP2;           // P2
            //apdu.bP3 = byP3;           // P3
            apdu.bP3 = (byte)bytesToSend.Length;

            int x = 0;
            while (x < bytesToSend.Length)
            {
                apdu.Data[x] = bytesToSend[x];
                x++;
            }

            apdu.IsSend = true;
            //lstOutput.Items.Add("Submit IC");
            CLogger.Append("SENDING DATA TO CARD - COMMAND SENDER", CLogger.COMM);

            PerformTransmitAPDU(ref apdu);


            int ReaderLen, dwState, ATRLen, indx;
            byte[] ATRVal = new byte[31];
            ATRLen = 32;

            ReaderLen = 0;
            dwState = 0;

            retCode = ModWinsCard.SCardStatus(hCard, _strLectora, ref ReaderLen, ref dwState, ref Protocol, ref ATRVal[0], ref ATRLen);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
            {//   return "ERROR";
                CLogger.Append("retCode != ModWinsCard.SCARD_S_SUCCESS", CLogger.COMM);
                return false;
            }
            //'Format ATRVal returned and display string as ATR value
            tmpStr = "";
            for (indx = 0; indx < ATRLen; indx++)
            {
                tmpStr = tmpStr + string.Format("{0:x2}", ATRVal[indx]).ToUpper();
            }

            // return tmpStr;

            return true;

        }



        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// CAMBIAR O CREAR NUEVO PIN
        /// </summary>
        /// <param name="strDataToPin"></param>
        /// <returns></returns>
        /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public bool ChangePin(string strDataToPin,byte[] byICSubmitCode,byte byCodeNo)
        {

            SubmitIC(byICSubmitCode, byCodeNo);
            if (retcode != ModWinsCard.SCARD_S_SUCCESS)
            {
                return false;
            }

            //Send IC Code
            apdu.Data = array;

            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            Byte[] bytesToSend = encoding.GetBytes(strDataToPin);

            apdu.bCLA = 0x80;          // CLA
            apdu.bINS = 0x24;          // INS
            apdu.bP1 = 0x00;           // P1
            apdu.bP2 = 0x00;           // P2
            apdu.bP3 = 0x08;           // P3
            //apdu.bP3 = (byte)bytesToSend.Length;

            int x = 0;
            while (x < bytesToSend.Length)
            {
                apdu.Data[x] = bytesToSend[x];
                x++;
            }

            apdu.IsSend = true;
            //lstOutput.Items.Add("Submit IC");
            CLogger.Append("SENDING DATA TO CARD - COMMAND SENDER", CLogger.COMM);

            PerformTransmitAPDU(ref apdu);

            int ReaderLen, dwState, ATRLen, indx;
            byte[] ATRVal = new byte[31];
            ATRLen = 32;

            ReaderLen = 0;
            dwState = 0;

            retCode = ModWinsCard.SCardStatus(hCard, _strLectora, ref ReaderLen, ref dwState, ref Protocol, ref ATRVal[0], ref ATRLen);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
            {//   return "ERROR";
                CLogger.Append("retCode != ModWinsCard.SCARD_S_SUCCESS", CLogger.COMM);
                return false;
            }
            //'Format ATRVal returned and display string as ATR value
            tmpStr = "";
            for (indx = 0; indx < ATRLen; indx++)
            {
                tmpStr = tmpStr + string.Format("{0:x2}", ATRVal[indx]).ToUpper();
            }

            // return tmpStr;

            return true;

        }

      //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// SELECT FILE VY FILE ID
        /// </summary>
        /// <param name="strDataToPin"></param>
        /// <returns></returns>
        /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public bool SelectFileByFileID(byte[] byFileID)
        {
            //Send IC Code
            apdu.Data = array;

            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
          
            apdu.bCLA = 0x80;          // CLA
            apdu.bINS = 0xA4;          // INS
            //apdu.bP1 = 0x00;           // P1
            apdu.bP1 = 0x00;
            apdu.bP2 = 0x00;           // P2
            apdu.bP3 = 0x02;           // P3
            //apdu.bP3 = (byte)bytesToSend.Length;

            int x = 0;
            while (x < byFileID.Length)
            {
                apdu.Data[x] = byFileID[x];
                x++;
            }

            apdu.IsSend = true;
            //lstOutput.Items.Add("Submit IC");
            CLogger.Append("SENDING DATA TO CARD - COMMAND SENDER", CLogger.COMM);

            PerformTransmitAPDU(ref apdu);

            int ReaderLen, dwState, ATRLen, indx;
            byte[] ATRVal = new byte[31];
            ATRLen = 32;

            ReaderLen = 0;
            dwState = 0;

            retCode = ModWinsCard.SCardStatus(hCard, _strLectora, ref ReaderLen, ref dwState, ref Protocol, ref ATRVal[0], ref ATRLen);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
            {//   return "ERROR";
                CLogger.Append("retCode != ModWinsCard.SCARD_S_SUCCESS", CLogger.COMM);
                return false;
            }
            //'Format ATRVal returned and display string as ATR value
            tmpStr = "";
            for (indx = 0; indx < ATRLen; indx++)
            {
                tmpStr = tmpStr + string.Format("{0:x2}", ATRVal[indx]).ToUpper();
            }

            // return tmpStr;

            return true;

        }

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// SUBMIT CODE TO CARD - REPETIDO - 
        /// </summary>
        /// <param name="strDataToPin"></param>
        /// <returns></returns>
        /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public bool SubmitCodeToCard(string strDataToCard,byte byP1)
        {

            //Send IC Code
            apdu.Data = array;

            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
            Byte[] bytesToSend = encoding.GetBytes(strDataToCard);

            apdu.bCLA = 0x80;          // CLA
            apdu.bINS = 0x20;          // INS
            //apdu.bP1 = 0x00;           // P1
            apdu.bP1 = byP1;
            apdu.bP2 = 0x00;           // P2
            apdu.bP3 = 0x08;           // P3
            //apdu.bP3 = (byte)bytesToSend.Length;

            int x = 0;
            while (x < bytesToSend.Length)
            {
                apdu.Data[x] = bytesToSend[x];
                x++;
            }

            apdu.IsSend = true;
            //lstOutput.Items.Add("Submit IC");
            CLogger.Append("SENDING DATA TO CARD - COMMAND SENDER", CLogger.COMM);

            PerformTransmitAPDU(ref apdu);

            int ReaderLen, dwState, ATRLen, indx;
            byte[] ATRVal = new byte[31];
            ATRLen = 32;

            ReaderLen = 0;
            dwState = 0;

            retCode = ModWinsCard.SCardStatus(hCard, _strLectora, ref ReaderLen, ref dwState, ref Protocol, ref ATRVal[0], ref ATRLen);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
            {//   return "ERROR";
                CLogger.Append("retCode != ModWinsCard.SCARD_S_SUCCESS", CLogger.COMM);
                return false;
            }
            //'Format ATRVal returned and display string as ATR value
            tmpStr = "";
            for (indx = 0; indx < ATRLen; indx++)
            {
                tmpStr = tmpStr + string.Format("{0:x2}", ATRVal[indx]).ToUpper();
            }

            // return tmpStr;

            return true;

        }

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Get Card Info - RECUPERAR INFO DE LA TARJETA
        /// </summary>
        /// <param name="strDataToPin"></param>
        /// <returns></returns>
        /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public bool GetCardInfo(byte byP1CardInfo,byte byP3CardInfo)
        {
            //Send IC Code
            apdu.Data = array;

            apdu.bCLA = 0x80;          // CLA
            apdu.bINS = 0x14;          // INS
            //apdu.bP1 = 0x00;           // P1
            apdu.bP1 = byP1CardInfo;
            apdu.bP2 = 0x00;           // P2
            apdu.bP3 = byP3CardInfo;           // P3
            //apdu.bP3 = (byte)bytesToSend.Length;


            apdu.IsSend = true;
            //lstOutput.Items.Add("Submit IC");
            CLogger.Append("SENDING DATA TO CARD - COMMAND SENDER", CLogger.COMM);

            PerformTransmitAPDU(ref apdu);

            int ReaderLen, dwState, ATRLen, indx;
            byte[] ATRVal = new byte[31];
            ATRLen = 32;

            ReaderLen = 0;
            dwState = 0;

            retCode = ModWinsCard.SCardStatus(hCard, _strLectora, ref ReaderLen, ref dwState, ref Protocol, ref ATRVal[0], ref ATRLen);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
            {//   return "ERROR";
                CLogger.Append("retCode != ModWinsCard.SCARD_S_SUCCESS", CLogger.COMM);
                return false;
            }
            //'Format ATRVal returned and display string as ATR value
            tmpStr = "";
            for (indx = 0; indx < ATRLen; indx++)
            {
                tmpStr = tmpStr + string.Format("{0:x2}", ATRVal[indx]).ToUpper();
            }

            // return tmpStr;

            return true;

        }

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        /// Update ATR - NUEVO ATR
        /// </summary>
        /// <param name="strDataToPin"></param>
        /// <returns></returns>
        /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public bool UpdateATR(byte[] byNewATR, byte num_historical_byte,byte[] byICCode,byte byCodeNo)
        {
           // string tmpStr;
            int indx;
            byte[] tmpAPDU=new byte[byNewATR.Length];
            string[] ctrbyte = new string[14]; 

            //Select FF07 file
            SelectFile(0xFF, 0x07);

            if (retcode != ModWinsCard.SCARD_S_SUCCESS)
            {
                return false;
            }

            /*tmpStr = "";
            for (indx = 0; indx < 1; indx++)
                tmpStr = tmpStr + " " + string.Format("{0:X2}", RecvBuff[indx]);
            */
            // Submit Issuer Code
            SubmitIC(byICCode,byCodeNo);
            if (retcode != ModWinsCard.SCARD_S_SUCCESS)
            {
                return false;
            }


            tmpAPDU = byNewATR;


            //////////////////////////////////////////////////////////////////////////////////////////////
            string strTemp=null;
            for (indx = 0; indx < tmpAPDU.Length; indx++)
            {
                strTemp = strTemp +string.Format("{0:x2}", tmpAPDU[indx]).ToUpper();
            }

            CLogger.Append("TMPAPDU: " + strTemp, CLogger.COMM);
            ///////////////////////////////////////////////////////////////////////////////////////////////

            byte byLen = (byte) tmpAPDU.Length;
            //writeRecord(0x00, 0x00, 35, byLen, ref tmpAPDU);

            int inInit = 0;

            byte[] byAPDU = new byte[35];
            int j = 2;
            switch(num_historical_byte)
            {
                case 0x0A:
                        CLogger.Append("CASE 0x0A: " + string.Format("{0:x2}", num_historical_byte).ToUpper(), CLogger.COMM);
                         inInit=tmpAPDU.Length - 10;

                        while (inInit < (tmpAPDU.Length))
                        {
                            byAPDU[j] = tmpAPDU[inInit];
                            inInit++;
                            j++;
                        }
                    break;
                case 0x0B:
                        CLogger.Append("CASE 0x0B: " + string.Format("{0:x2}", num_historical_byte).ToUpper(), CLogger.COMM);
                        
                         inInit= tmpAPDU.Length - 11;
                        while (inInit < (tmpAPDU.Length))
                        {
                            byAPDU[j] = tmpAPDU[inInit];
                            inInit++;
                            j++;
                        }
                    break;
                case 0x0C:
                        CLogger.Append("CASE 0x0C: " + string.Format("{0:x2}", num_historical_byte).ToUpper(), CLogger.COMM);
                         inInit = tmpAPDU.Length - 12;
                    
                        while (inInit < (tmpAPDU.Length))
                        {
                            byAPDU[j] = tmpAPDU[inInit];
                            inInit++;
                            j++;
                        }
                    break;                
                case 0x0D:
                        CLogger.Append("CASE 0x0D: " + string.Format("{0:x2}", num_historical_byte).ToUpper(), CLogger.COMM);
                         inInit = tmpAPDU.Length - 13;
                        while (inInit < (tmpAPDU.Length))
                        {
                            byAPDU[j] = tmpAPDU[inInit];
                            inInit++;
                            j++;
                        }
                    break;
                case 0x0E:
                        CLogger.Append("CASE 0x0E: " + string.Format("{0:x2}", num_historical_byte).ToUpper(), CLogger.COMM);
                         inInit = tmpAPDU.Length - 14;                    
                       // CLogger.Append("APDU: "+tmpAPDU.Length+" - inINIT: " + inInit.ToString(), CLogger.COMM);

                        while (inInit < (tmpAPDU.Length))
                        {
                            byAPDU[j] = tmpAPDU[inInit];

                           // CLogger.Append("COPY: " + string.Format("{0:x2}", byAPDU[j]).ToUpper(), CLogger.COMM);

                            inInit++;
                            j++;
                        }
                    break;
                case 0x0F:
                        CLogger.Append("CASE 0x0F: " + string.Format("{0:x2}", num_historical_byte).ToUpper(), CLogger.COMM);
                         inInit = tmpAPDU.Length - 15;
                        while (inInit < (tmpAPDU.Length))
                        {
                            byAPDU[j] = tmpAPDU[inInit];
                            inInit++;
                            j++;
                        }
                    break;
                default:
                    CLogger.Append("CASE DEFAULT: " + string.Format("{0:x2}", num_historical_byte).ToUpper(), CLogger.COMM);
                    break;
            }
            byAPDU[0] = 0x11;   //ESTA ES LA VELOCIDAD  - 9600
            byAPDU[1] = num_historical_byte;
            

                writeRecord(0x00, 0x00, 35, 0x11, ref byAPDU);
            //writeRecord(0x00, 0x00, 35, 0x11, ref tmpAPDU);
            return true;
        }


      /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
      /// /////////////////////////////////////////////////////////////////////////////////////////////////////
      
        private void writeRecord(int caseType, byte RecNo, byte maxLen, byte DataLen, ref byte[] ApduIn)
        {
           // CLogger.Append("Estoy dentro", CLogger.COMM);

            if (caseType == 1)    // If card data is to be erased before writing new data. Re-initialize card values to $00
            {
             //   CLogger.Append("DENTRO CASE", CLogger.COMM);
                apdu.bCLA = 0x80;        // CLA
                apdu.bINS = 0xD2;        // INS
                apdu.bP1 = RecNo;		 // Record No
                apdu.bP2 = 0x00;         // P2
                apdu.bP3 = maxLen;        // Length of Data

                apdu.IsSend = true;

                for (i = 0; i < maxLen; i++)
                {
                  //  CLogger.Append("DENTRO for i: " + ApduIn[i].ToString(), CLogger.COMM);
                    //CLogger.Append("DENTRO for Max: " + maxLen.ToString(), CLogger.COMM);
                    apdu.Data[i] =  ApduIn[i];
                  //  CLogger.Append("APDU: " + apdu.Data[i].ToString(), CLogger.COMM);
                }
                
                PerformTransmitAPDU(ref apdu);
             //   CLogger.Append("Pase PErform", CLogger.COMM);
            }
            
          //  CLogger.Append("Pase if", CLogger.COMM);
            //Write data to card
            apdu.bCLA = 0x80;       // CLA
            apdu.bINS = 0xD2;       // INS
            apdu.bP1 = RecNo;       // Record No
            apdu.bP2 = 0x00;        // P2
            apdu.bP3 = DataLen;     // Length of Data

            apdu.IsSend = true;

            for (i = 0; i < maxLen; i++)
                apdu.Data[i] = ApduIn[i];

          //  lstOutput.Items.Add("Write to FF 02");
          //  EscribirLog("Write to FF 02");
            CLogger.Append("Write to FF02", CLogger.COMM);
                        
            PerformTransmitAPDU(ref apdu);

        }
        
        private void PerformTransmitAPDU(ref ModWinsCard.APDURec apdu)
        {
           // CLogger.Append("Estoy dentro", CLogger.COMM);

            ModWinsCard.SCARD_IO_REQUEST SendRequest;
            ModWinsCard.SCARD_IO_REQUEST RecvRequest;

            SendBuff[0] = apdu.bCLA;
            SendBuff[1] = apdu.bINS;
            SendBuff[2] = apdu.bP1;
            SendBuff[3] = apdu.bP2;
            SendBuff[4] = apdu.bP3;

            if (apdu.IsSend)
            {
                for (indx = 0; indx < apdu.bP3; indx++)
                    SendBuff[5 + indx] = apdu.Data[indx];

                SendBuffLen = 5 + apdu.bP3;
                RecvBuffLen = 2;
            }
            else
            {
                SendBuffLen = 5;
                RecvBuffLen = 2 + apdu.bP3;
            }
            
            SendRequest.dwProtocol = Aprotocol;
            SendRequest.cbPciLength = 8;

            RecvRequest.dwProtocol = Aprotocol;
            RecvRequest.cbPciLength = 8;


            ////////////// DEBUG /////////////////////////////////////////////////////
            //string strTemp = null;
            //for (indx = 0; indx < SendBuff.Length; indx++)
            //{
            //    strTemp = strTemp + string.Format("{0:x2}", SendBuff[indx]).ToUpper();
            //}
            //CLogger.Append("WRITE DATA: " + strTemp, CLogger.COMM);
            //////////////////////////////////////////////////////////////////////////


            retcode = ModWinsCard.SCardTransmit(hCard, ref SendRequest, ref SendBuff[0], SendBuffLen, ref SendRequest, ref RecvBuff[0], ref RecvBuffLen);


            if (retcode != ModWinsCard.SCARD_S_SUCCESS)  //ACA VOY A ESCRIBIR UN LOG
            {
                //      lstOutput.Items.Add("SCardTransmit Error!");  LOG
                CLogger.Append("ERROR: SCardTransmit Error!", CLogger.COMM);
                //   EscribirLog("SCardTransmit Error!");
            }
            else
            {
                //lstOutput.Items.Add("SCardTransmit OK...");       LOG
                CLogger.Append("SCardTransmit OK...", CLogger.COMM);
                //   EscribirLog("SCardTransmit OK...");
            }

            sTemp = "";
            // do loop for sendbuffLen
            for (indx = 0; indx < SendBuffLen; indx++)
                sTemp = sTemp + " " + string.Format("{0:X2}", SendBuff[indx]);



            CLogger.Append("Send Buffer: " + sTemp, CLogger.COMM);


            sTemp = "";
            for (indx = 0; indx < RecvBuffLen; indx++)
                sTemp = sTemp + " " + string.Format("{0:X2}", RecvBuff[indx]);

            CLogger.Append("Receive Buffer: " + sTemp, CLogger.COMM);


            if (apdu.IsSend == false)
            {
                for (indx = 0; indx < apdu.bP3 + 2; indx++)
                    apdu.Data[indx] = RecvBuff[indx];
            }

            //   lstOutput.SelectedIndex = lstOutput.Items.Count - 1;

        }

        private void SelectFile(byte HiAddr, byte LoAddr)
        {
            // Select FF 02
            apdu.Data = array;

            apdu.bCLA = 0x080;       // CLA
            apdu.bINS = 0x0A4;       // INS
            apdu.bP1 = 0x00;         // P1
            apdu.bP2 = 0x00;         // P2
            apdu.bP3 = 0x02;         // P3

            apdu.Data[0] = HiAddr;      // Value of High Byte
            apdu.Data[1] = LoAddr;      // Value of Low Byte

            apdu.IsSend = true;
            PerformTransmitAPDU(ref apdu);
        }
        public int Asc(string character)
        {
            if (character.Length == 1)
            {
                System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
                int intAsciiCode = (int)asciiEncoding.GetBytes(character)[0];
                return (intAsciiCode);
            }
            else
            {
                CLogger.Append("Asc(...): Character is not valid.", CLogger.COMM);
                throw new Exception("Character is not valid.");
                //EscribirLog("Character is not valid");
            
            }

        }

        public byte HexStringToByte(string hexByte)
        {
            return Byte.Parse(hexByte, NumberStyles.HexNumber);
        }

        public string LeerDatos(int inFileSelector)
        {
            
            int indx;
            //string ChkStr;

            // Check User File selected by user
            if (inFileSelector == 1)
            {
                HiAddr = 0xAA;
                LoAddr = 0x11;
                dataLen = 0x0A;
                //ChkStr = "91 00";
            }

            if (inFileSelector == 2)
            {
                HiAddr = 0xBB;
                LoAddr = 0x22;
                dataLen = 0x10;
                //ChkStr = "91 01";
            }

            if (inFileSelector == 3)
            {
                HiAddr = 0xCC;
                LoAddr = 0x33;
                dataLen = 0x20;
                //ChkStr = "91 02";
            }

            // Select User File
            SelectFile(HiAddr, LoAddr);

            if (retcode != ModWinsCard.SCARD_S_SUCCESS)
            {
                return "ERROR";
            }

            // Read First Record of User File selected
            readRecord(0x00, dataLen);

            if (retcode != ModWinsCard.SCARD_S_SUCCESS)
            {
                return "ERROR";
            }

            // Display data read from card to textbox
            tmpStr = "";
            indx = 0;

            while (RecvBuff[indx] != 0x00)
            {                
                    tmpStr = tmpStr + Chr(RecvBuff[indx]);
                   
                    indx = indx + 1;
            }

            CLogger.Append("Datos Leidos:" + tmpStr, CLogger.COMM);
            return tmpStr;

         //   lstOutput.Items.Add("Data read from card is displayed");
          //  lstOutput.SelectedIndex = lstOutput.Items.Count - 1;
        }
        private void readRecord(byte RecNo, byte dataLen)
        {
            apdu.Data = array;

            // Read data from card
            apdu.bCLA = 0x80;        // CLA
            apdu.bINS = 0xB2;         // INS
            apdu.bP1 = RecNo;        // Record No
            apdu.bP2 = 0x00;         // P2
            apdu.bP3 = dataLen;      // Length of Data

            apdu.IsSend = false;

            PerformTransmitAPDU(ref apdu);

        }

        Char Chr(int i)
        {
            //Return the character of the given character value
            return Convert.ToChar(i);
        }

        /// <summary>
        /// // Create format to the card:
        /// </summary>
        /// <param name="strLine"></param>
        public bool DarFormato(byte[] byFormatoICCode,byte byCodeNo)
        {

            //Send IC Code
           // lstOutput.Items.Add("Submit Code");
            CLogger.Append("Submit Code", CLogger.COMM);
            SubmitIC(byFormatoICCode, byCodeNo);


            if (retcode != ModWinsCard.SCARD_S_SUCCESS)
            {
                CLogger.Append("ERROR Card UNSUCCESS", CLogger.COMM);
                return false;
            }

            //Select FF 02
            //lstOutput.Items.Add("Select FF 02");
            CLogger.Append("Select FF 02", CLogger.COMM);

            SelectFile(0xFF, 0x02);
            if (retcode != ModWinsCard.SCARD_S_SUCCESS)
            {
                CLogger.Append("ERROR Card UNSUCCESS", CLogger.COMM);
                return false;
            }

            /* Write to FF 02
            This will create 3 User files, no Option registers and
            Security Option registers defined, Personalization bit is not set */
            tmpArray[0] = 0x00;      // 00    Option registers
            tmpArray[1] = 0x00;      // 00    Security option register
            tmpArray[2] = 0x03;      // 03    No of user files
            tmpArray[3] = 0x00;      // 00    Personalization bit

            writeRecord(0x00, 0x00, 0x04, 0x04, ref tmpArray);

            //Select FF 04
            CLogger.Append("Select FF 04", CLogger.COMM);
           // lstOutput.Items.Add("Select FF 04");
            SelectFile(0xFF, 0x04);

            // Send IC Code
            //lstOutput.Items.Add("Submit Code");
            CLogger.Append("Submit Code", CLogger.COMM);
            SubmitIC(byFormatoICCode,byCodeNo);

            if (retcode != ModWinsCard.SCARD_S_SUCCESS)
            {
                CLogger.Append("ERROR Card UNSUCCESS", CLogger.COMM);
                return false;
            }

            /* Write to FF 04
             Write to first record of FF 04 */
            tmpArray[0] = 0x0A;       // 10    Record length
            tmpArray[1] = 0x03;       // 3     No of records
            tmpArray[2] = 0x00;       // 00    Read security attribute
            tmpArray[3] = 0x00;       // 00    Write security attribute
            tmpArray[4] = 0xAA;       // AA    File identifier
            tmpArray[5] = 0x11;       // 11    File identifier
            tmpArray[6] = 0x00;       // 00    File Access Flag Bit


            writeRecord(0x00, 0x00, 0x06, 0x06, ref tmpArray);

            if (retcode != ModWinsCard.SCARD_S_SUCCESS)
            {
                CLogger.Append("ERROR Card UNSUCCESS", CLogger.COMM);
                return false;
            }

            //Write to second record of FF 04
            tmpArray[0] = 0x10;			// 16    Record length
            tmpArray[1] = 0x02;			// 2     No of records
            tmpArray[2] = 0x00;			// 00    Read security attribute
            tmpArray[3] = 0x00;			// 00    Write security attribute
            tmpArray[4] = 0xBB;			// BB    File identifier
            tmpArray[5] = 0x22;			// 22    File identifier
            tmpArray[6] = 0x00;         // 00    File Access Flag Bit

            writeRecord(0x00, 0x01, 0x06, 0x06, ref tmpArray);

            if (retcode != ModWinsCard.SCARD_S_SUCCESS)
            {
                CLogger.Append("ERROR Card UNSUCCESS", CLogger.COMM);
                return false;
            }

          //  lstOutput.Items.Add("User File BB 22 is defined");
            CLogger.Append("User File BB 22 is defined", CLogger.COMM);

            //Write to third record of FF 04
            tmpArray[0] = 0x20;       // 32    Record length
            tmpArray[1] = 0x04;       // 4     No of records
            tmpArray[2] = 0x00;       // 00    Read security attribute
            tmpArray[3] = 0x00;       // 00    Write security attribute
            tmpArray[4] = 0xCC;       // CC    File identifier
            tmpArray[5] = 0x33;       // 33    File identifier
            tmpArray[6] = 0x00;       // 00    File Access Flag Bit

            writeRecord(0x00, 0x02, 0x06, 0x06, ref tmpArray);

            if (retcode != ModWinsCard.SCARD_S_SUCCESS)
            {
                CLogger.Append("ERROR Card UNSUCCESS", CLogger.COMM);
                return false;
            }

           // CLogger.Append("User File CC 33 is defined", CLogger.COMM);
            //lstOutput.Items.Add("User File CC 33 is defined");
            //lstOutput.SelectedIndex = lstOutput.Items.Count - 1;

           // GBUserFile.Enabled = true;
           // GroupBox2.Enabled = true;
            return true;
        }


        /// <summary>
        /// // Submit the IC
        /// </summary>
        /// <param name="strLine"></param>
        private void SubmitIC(byte[] byICCode,byte byCodeNo)
        {

            //Send IC Code
            apdu.Data = array;

            apdu.bCLA = 0x80;          // CLA
            apdu.bINS = 0x20;          // INS
            //apdu.bP1 = 0x07;           // P1
            apdu.bP1 = byCodeNo;
            apdu.bP2 = 0x00;           // P2
            apdu.bP3 = 0x08;           // P3

            apdu.Data[0] = byICCode[0];       // A
            apdu.Data[1] = byICCode[1];       // C
            apdu.Data[2] = byICCode[2];       // O
            apdu.Data[3] = byICCode[3];       // S
            apdu.Data[4] = byICCode[4];       // T
            apdu.Data[5] = byICCode[5];       // E
            apdu.Data[6] = byICCode[6];       // S
            apdu.Data[7] = byICCode[7];       // T

            apdu.IsSend = true;
            //lstOutput.Items.Add("Submit IC");
            CLogger.Append("Submit IC", CLogger.COMM);

            PerformTransmitAPDU(ref apdu);
        }

   /// <summary>
        /// // Create a writer and open the file:
        /// </summary>
        /// <param name="strLine"></param>
        public void EscribirLog(string strLine)
        {
            StreamWriter log;
            string strDate;
            strDate = DateTime.Today.ToString();

            string Path = @"C:\Fabio\Pr\Hs\DLL lectora\hsdll\Log";
       

          //  Response.Write(@"<script language='javascript'>alert('Update is successful.')</script>");
                    if (!System.IO.Directory.Exists(Path))
            {
                     System.IO.Directory.CreateDirectory(Path);
             }
            if (!File.Exists(@"C:\Fabio\Pr\Hs\DLL lectora\hsdll\Log\logfile" + strDate + ".txt"))
            {
              //  Console.WriteLine("{0} already exists.", "logfile");

                log = new StreamWriter(@"C:\Fabio\Pr\Hs\DLL lectora\hsdll\Log\logfile" + strDate + ".txt");
                
            }
            else
            {
                log = File.AppendText("logfile" + strDate + ".txt");
            }

            // Write to the file:
            log.WriteLine(DateTime.Now);
            log.WriteLine(": ");
            log.WriteLine(strLine);
            log.WriteLine();

            // Close the stream:
            log.Close();

        }
      
        #endregion
        ///////////////////////////////////////////////////////////////////////////////////////////////////////     

      #endregion

        #region Metodos Contexto
        public bool establecerContexto()
        {
            ReaderCount = 255;

            //Establish context and obtain hContext handle
            retCode = ModWinsCard.SCardEstablishContext(ModWinsCard.SCARD_SCOPE_USER, 0, 0, ref hContext);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return false;
            else
                return true;
           
        }
        public string listarLectoras()
        { 
        
			//used to split null delimited strings into string arrays
		
			string ReaderList = ""+Convert.ToChar(0);
			
			string temp = ""+Convert.ToChar(0);

			int pcchReaders= -1;
			
			// List PC/SC card readers installed in the system
			retCode = ModWinsCard.SCardListReaders(this.hContext, temp, ref ReaderList, ref pcchReaders);
            _strLectora = ReaderList;
            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return "ERROR";
            else
                return ReaderList;

        }
        public bool conectar() 
        {
        
			//'Connect to selected reader using hContext handle
			//'and obtain valid hCard handle
			retCode = ModWinsCard.SCardConnect(hContext, _strLectora, ModWinsCard.SCARD_SHARE_EXCLUSIVE,
				ModWinsCard.SCARD_PROTOCOL_T0 | ModWinsCard.SCARD_PROTOCOL_T1, 
				ref hCard, ref Protocol);
            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return false;
            else
                return true;
        }

        public bool comenzarTransaccion()
		{
			retCode = ModWinsCard.SCardBeginTransaction(hCard);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return false;
            else
                return true;
		}

        public string leerATR()
		{
			int ReaderLen, dwState, ATRLen, indx;
			byte[] ATRVal=new byte[31];
			ATRLen = 32;

			ReaderLen = 0;
			dwState = 0;

			retCode = ModWinsCard.SCardStatus(hCard, _strLectora, ref ReaderLen, ref dwState, 
				ref Protocol, ref ATRVal[0], ref ATRLen);
            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return "ERROR";
            
			//'Format ATRVal returned and display string as ATR value
			tmpStr = "";
			for(indx = 0; indx < ATRLen; indx++)
			{
				tmpStr = tmpStr +  string.Format("{0:x2}",ATRVal[indx]).ToUpper(); 
			}
            return tmpStr;

		}
     


        public bool terminarTransaccion()
 		{
			retCode = ModWinsCard.SCardEndTransaction(hCard, ModWinsCard.SCARD_LEAVE_CARD);
            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
            {
                return false;
            }
            else
                return true;
        }

        public bool desconectar()
        {
            retCode = ModWinsCard.SCardDisconnect(hCard, ModWinsCard.SCARD_UNPOWER_CARD);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return false;
            else
                return true;
        }

        public bool soltarContexto()
        {
            retCode = ModWinsCard.SCardReleaseContext(hContext);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return false;
            else
                return true;
        }


        #endregion
	
	
  }
}

/*
namespace HSCardReaderNamespace
{
    [ClassInterface(ClassInterfaceType.AutoDual)]
    public class HSCardReader
    {
        #region Properties
                string _strLectora;
                // variable declaration
                int Protocol, hContext, hCard, ReaderCount;
                int retCode;
                //byte[] sReaderList = new byte [255];
                string sReaderList;
                string sReaderGroup;
                string tmpStr;
                public ModWinsCard.SCARD_IO_REQUEST ioRequest = new ModWinsCard.SCARD_IO_REQUEST();
                int SendLen, RecvLen;
                byte[] SendBuff = new byte[262];
                byte[] RecvBuff = new byte[262];
                int indx;
        #endregion

		#region Metodos Principales
		public string identificarTarjeta()
		{
		string strATR="";
			if(!establecerContexto())
			{				
				return "ERROR en establecerContexto()";
			}
			if(listarLectoras()=="ERROR")
			{
				if(!soltarContexto())
				{
					return "ERROR GRAVE en listarLectoras()";
				}
				return "ERROR en listarLectoras()";
			}
			if(!conectar())
			{			
				if(!soltarContexto())
					{
						return "ERROR GRAVE en conectar()";
					}			
				return "ERROR en conectar()";
			}
			if(!comenzarTransaccion())
			{			
				if(!desconectar())
					{
						return "ERROR GRAVE 1 en comenzarTransaccion()";
					}
				if(!soltarContexto())
					{
						return "ERROR GRAVE 2 en comenzarTransaccion()";
					}			
				return "ERROR en comenzarTransaccion()";
			}
			strATR = leerATR();
			if(strATR=="ERROR")
			{
				if(!terminarTransaccion())
					{
						return "ERROR GRAVE 1 en leerATR()";
					}
				if(!desconectar())
					{
						return "ERROR GRAVE 2 en leerATR()";
					}
				if(!soltarContexto())
					{
						return "ERROR GRAVE 3 en leerATR()";
					}		
				return "ERROR en leerATR()";
			}
			if(!terminarTransaccion())
			{
				if(!desconectar())
						{
							return "ERROR GRAVE 1 en terminarTransaccion()";
						}
				if(!soltarContexto())
					{
						return "ERROR GRAVE 2 en terminarTransaccion()";
					}		
				return "ERROR en terminarTransaccion()";
			}
			if(!desconectar())
			{
				if(!soltarContexto())
					{
						return "ERROR GRAVE en desconectar()";
					}	
				return "ERROR en desconectar()";
			}
			if(!soltarContexto())
			{
				return "ERROR en soltarContexto()";
			}
			
			return strATR;
		}

        /// <summary>
        /// Escribir en la Tarjeta
        /// FD v1.01
        /// </summary>
        /// <returns></returns>
        public string EscribirenTarjeta(string DatosW)
        {
            string strATR = "";
            if (!establecerContexto())
            {
                return "ERROR en establecerContexto()";
            }
            if (listarLectoras() == "ERROR")
            {
                if (!soltarContexto())
                {
                    return "ERROR GRAVE en listarLectoras()";
                }
                return "ERROR en listarLectoras()";
            }
            if (!conectar())
            {
                if (!soltarContexto())
                {
                    return "ERROR GRAVE en conectar()";
                }
                return "ERROR en conectar()";
            }
            if (!comenzarTransaccion())
            {
                if (!desconectar())
                {
                    return "ERROR GRAVE 1 en comenzarTransaccion()";
                }
                if (!soltarContexto())
                {
                    return "ERROR GRAVE 2 en comenzarTransaccion()";
                }
                return "ERROR en comenzarTransaccion()";
            }

            if (!terminarTransaccion())
            {
                if (!desconectar())
                {
                    return "ERROR GRAVE 1 en terminarTransaccion()";
                }
                if (!soltarContexto())
                {
                    return "ERROR GRAVE 2 en terminarTransaccion()";
                }
                return "ERROR en terminarTransaccion()";
            }
            if (!desconectar())
            {
                if (!soltarContexto())
                {
                    return "ERROR GRAVE en desconectar()";
                }
                return "ERROR en desconectar()";
            }
            if (!soltarContexto())
            {
                return "ERROR en soltarContexto()";
            }

            return strATR;
        }
		#endregion
		
		
        #region Metodos
        public bool establecerContexto()
        {
            ReaderCount = 255;

            //Establish context and obtain hContext handle
            retCode = ModWinsCard.SCardEstablishContext(ModWinsCard.SCARD_SCOPE_USER, 0, 0, ref hContext);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return false;
            else
                return true;
           
        }
        public string listarLectoras()
        { 
        
			//used to split null delimited strings into string arrays
		
			string ReaderList = ""+Convert.ToChar(0);
			
			string temp = ""+Convert.ToChar(0);

			int pcchReaders= -1;
			
			// List PC/SC card readers installed in the system
			retCode = ModWinsCard.SCardListReaders(this.hContext, temp, ref ReaderList, ref pcchReaders);
            _strLectora = ReaderList;
            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return "ERROR";
            else
                return ReaderList;

        }
        public bool conectar() 
        {
        
			//'Connect to selected reader using hContext handle
			//'and obtain valid hCard handle
			retCode = ModWinsCard.SCardConnect(hContext, _strLectora, ModWinsCard.SCARD_SHARE_EXCLUSIVE,
				ModWinsCard.SCARD_PROTOCOL_T0 | ModWinsCard.SCARD_PROTOCOL_T1, 
				ref hCard, ref Protocol);
            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return false;
            else
                return true;
        }

        public bool comenzarTransaccion()
		{
			retCode = ModWinsCard.SCardBeginTransaction(hCard);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return false;
            else
                return true;
		}

        public string leerATR()
		{
			int ReaderLen, dwState, ATRLen, indx;
			byte[] ATRVal=new byte[31];
			ATRLen = 32;

			ReaderLen = 0;
			dwState = 0;

			retCode = ModWinsCard.SCardStatus(hCard, _strLectora, ref ReaderLen, ref dwState, 
				ref Protocol, ref ATRVal[0], ref ATRLen);
            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return "ERROR";
            
			//'Format ATRVal returned and display string as ATR value
			tmpStr = "";
			for(indx = 0; indx < ATRLen; indx++)
			{
				tmpStr = tmpStr +  string.Format("{0:x2}",ATRVal[indx]).ToUpper(); 
			}
            return tmpStr;

		}

        public bool terminarTransaccion()
 		{
			retCode = ModWinsCard.SCardEndTransaction(hCard, ModWinsCard.SCARD_LEAVE_CARD);
            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
            {
                return false;
            }
            else
                return true;
        }

        public bool desconectar()
        {
            retCode = ModWinsCard.SCardDisconnect(hCard, ModWinsCard.SCARD_UNPOWER_CARD);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return false;
            else
                return true;
        }

        public bool soltarContexto()
        {
            retCode = ModWinsCard.SCardReleaseContext(hContext);

            if (retCode != ModWinsCard.SCARD_S_SUCCESS)
                return false;
            else
                return true;
        }

        #endregion
    }
}
     
*/